#include <stdio.h>
#include <DS1302.h>
#include "TM1637.h"

//时钟显示模块管脚定义  
#define CLK 5 
#define DIO 4
TM1637 tm1637(CLK,DIO);

//时钟模块管脚定义
#define kCePin   14 // 复位引脚
#define kIoPin   12 // 数据引脚
#define kSclkPin 13 // 时钟引脚
DS1302 rtc(kCePin, kIoPin, kSclkPin);

// 时间分隔符闪烁标识
bool ShowPoint = true;
//时间和日期交替显示
int showCount = 0;

namespace {

String dayAsString(const Time::Day day) {
  switch (day) {
    case Time::kSunday: return "Sunday";
    case Time::kMonday: return "Monday";
    case Time::kTuesday: return "Tuesday";
    case Time::kWednesday: return "Wednesday";
    case Time::kThursday: return "Thursday";
    case Time::kFriday: return "Friday";
    case Time::kSaturday: return "Saturday";
  }
  return "(unknown day)";
}
}

void printTime() {
  // 从模块获得当前时间
  Time t = rtc.time();

  // 星期几
  const String day = dayAsString(t.day);

  // 格式化时间数据
  char buf[50];
  snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
           day.c_str(),
           t.yr, t.mon, t.date,
           t.hr, t.min, t.sec);
  Serial.println(buf);
}

void showTime(){
  // 从模块获得当前时间
  Time t = rtc.time();
  int h = t.hr;
  int mn = t.min;
 
  int b0 = h / 10;
  int b1 = h % 10;
 
  int b2 = mn / 10;
  int b3 = mn % 10;
  
  tm1637.display(0, b0);
  tm1637.display(1, b1);
  tm1637.point(ShowPoint);
  tm1637.display(2, b2);
  tm1637.display(3, b3);
  
  ShowPoint = !ShowPoint;
}

void showDate(){
  // 从模块获得当前时间
  Time t = rtc.time();
  int m = t.mon;
  int d = t.date;
 
  int m0 = m / 10;
  int m1 = m % 10;
 
  int d2 = d / 10;
  int d3 = d % 10;
  
  tm1637.display(0, m0);
  tm1637.display(1, m1);
  tm1637.point(false);
  tm1637.display(2, d2);
  tm1637.display(3, d3);
}  // namespace


void setTime(){
   // 设置初始时间为 2018-1-18,17:28:00 星期四
   Time t(2023, 5, 28, 10, 59, 0, Time::kSunday);
   rtc.time(t);
}

void setup() {
   Serial.begin(9600);
   rtc.writeProtect(false);
   rtc.halt(false);
   
   //时钟显示模块的初始化
   tm1637.init();
   //设置亮度0-7
   tm1637.set(2);
   // 设置完时间后要注释掉，否则下次通电会重置时间
   //setTime();
}


void loop() {
  //每隔10s显示一次日期
  if( showCount <= 10 )
  {
    showTime();
    showCount++;
    delay(1000);
  }
  else
  {
    showDate();
    showCount = 0; 
    delay(2000);  
  }

}
